﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace YArchitech.Plumbing
{
	public class BeamDataManage
	{
		public void Init()
		{
			this.beamList.Clear();
			this.joinsList.Clear();
			this.rectsList.Clear();
			this.maxRect = null;
		}

		public bool Cal(ref string szErr)
		{
			this.SeparaBeams();
			foreach (List<BeamData> list in this.joinsList)
			{
				this.AnalysisBeamData(list);
			}
			if (this.rectsList == null || this.rectsList.Count < 1)
			{
				szErr = "主梁没有围成矩形闭合区域，可能主梁间距过大!";
				return false;
			}
			double num = 0.0;
			foreach (RectBeam rectBeam in this.rectsList)
			{
				if (rectBeam.Area() > num)
				{
					num = rectBeam.Area();
					this.maxRect = rectBeam;
				}
			}
			return true;
		}

		public void AnalysisBeamData(List<BeamData> list)
		{
			if (list == null || list.Count <= 0)
			{
				return;
			}
			List<BeamData> list2 = new List<BeamData>();
			foreach (BeamData beamData in list)
			{
				if (beamData.IsSelfParallel() && !list2.Contains(beamData))
				{
					RectBeam rectBeam = new RectBeam();
					rectBeam.beamParallelLeft = beamData;
					list2.Add(beamData);
					this.GetNextBeam(beamData, BeamDataManage.SearchStep.Parallel_Front, beamData, list, rectBeam);
				}
			}
		}

		public void GetNextBeam(BeamData rootBeam, BeamDataManage.SearchStep step, BeamData curBeam, List<BeamData> list, RectBeam sellist)
		{
			if (list == null || list.Count <= 0 || sellist == null)
			{
				return;
			}
			if (step == BeamDataManage.SearchStep.Vertical_Down && (from bb in list
			where rootBeam.IsJoinByPoint(bb, rootBeam.SPoint)
			select bb).ToList<BeamData>().Contains(curBeam))
			{
				sellist.beams.Add(curBeam);
				this.rectsList.Add(sellist);
				return;
			}
			sellist.beams.Add(curBeam);
			BeamData nextStepBeam = curBeam.GetNextStepBeam(step, list);
			if (nextStepBeam != null)
			{
				this.GetNextBeam(rootBeam, step, nextStepBeam, list, sellist);
			}
			if (step != BeamDataManage.SearchStep.Vertical_Down)
			{
				BeamDataManage.SearchStep searchStep = this.AddStep(step);
				BeamData nextStepBeam2 = curBeam.GetNextStepBeam(searchStep, list);
				if (nextStepBeam2 == null)
				{
					return;
				}
				RectBeam rectBeam = new RectBeam(sellist);
				switch (searchStep)
				{
				case BeamDataManage.SearchStep.Vertical_Up:
					rectBeam.beamVerticalDown = nextStepBeam2;
					break;
				case BeamDataManage.SearchStep.Parallel_Back:
					rectBeam.beamParallelRight = nextStepBeam2;
					break;
				case BeamDataManage.SearchStep.Vertical_Down:
					rectBeam.beamVerticalUp = nextStepBeam2;
					break;
				}
				this.GetNextBeam(rootBeam, searchStep, nextStepBeam2, list, rectBeam);
			}
		}

		private BeamDataManage.SearchStep AddStep(BeamDataManage.SearchStep step)
		{
			if (step == BeamDataManage.SearchStep.Parallel_Front)
			{
				return BeamDataManage.SearchStep.Vertical_Up;
			}
			if (step == BeamDataManage.SearchStep.Vertical_Up)
			{
				return BeamDataManage.SearchStep.Parallel_Back;
			}
			return BeamDataManage.SearchStep.Vertical_Down;
		}

		public void Add(BeamData d)
		{
			if (this.IsContain(d))
			{
				return;
			}
			this.beamList.Add(d);
		}

		public void AddElements(List<BeamData> entList)
		{
			foreach (BeamData d in entList)
			{
				this.Add(d);
			}
		}

		public bool IsContain(BeamData data)
		{
			return (from b in this.beamList
			where b.IsEqual(data)
			select b).ToList<BeamData>().Count > 0;
		}

		public void SeparaBeams()
		{
			while (this.beamList.Count > 0)
			{
				List<BeamData> list = new List<BeamData>();
				this.GetJoin(this.beamList[0], list);
				this.joinsList.Add(list);
			}
		}

		private void GetJoin(BeamData beam, List<BeamData> lists)
		{
			if (this.beamList.Contains(beam))
			{
				this.beamList.Remove(beam);
			}
			if (!lists.Contains(beam))
			{
				lists.Add(beam);
			}
			IEnumerable<BeamData> source = this.beamList;
            Func<BeamData, bool> ss9__0 = null;
			Func<BeamData, bool> predicate;
			if ((predicate = ss9__0) == null)
			{
				predicate = (ss9__0 = ((BeamData b) => b.IsJoin(beam)));
			}
			foreach (BeamData beam2 in source.Where(predicate).ToList<BeamData>())
			{
				this.GetJoin(beam2, lists);
			}
		}

		private List<BeamData> beamList = new List<BeamData>();

		public List<List<BeamData>> joinsList = new List<List<BeamData>>();

		public List<RectBeam> rectsList = new List<RectBeam>();

		public RectBeam maxRect;

		public enum SearchStep
		{
			Parallel_Front,
			Vertical_Up,
			Parallel_Back,
			Vertical_Down
		}
	}
}
